<?php 
namespace app\authorization\model;
use think\Model;
use think\Db;
use app\admin\model\AccessModel;
use app\common\lib\AccessAuthorization as AAZ;
use plugins\appmarket\controller\ConfigController as CC;
use app\authorization\model\RbacMenuModel as RMM; 

/**
 * 
 */
class ModuleModel extends Model
{

	/**
	 * 获取被授权的模块
	 */
	public function getModuleList( $userId )
	{
		$user = AAZ::getUserInfo( $userId );
		if( empty( $user ) ){
			return [];
		}
		$cid = $user[ 'company_id' ];
		$list = $this->getModuleListByCompanyId( $cid );
		return $list;
	}


	/**
	 * 读取公司列表
	 */
	public function getCompanyList()
	{
		return Db( 'company' )->field('id,company_name')->select();
	}

	/**
	 * 根据公司id获取已经被授权的模块列表
	 */
	public function getModuleListByCompanyId( $cid )
	{	
		$list = Db::view('module_store','id as store_id,name,title,describe,version,author,status,word')
			    ->view('module_menu','menu_id,company_id as company,code','module_store.menu_id=module_menu.menu_id and module_store.id=module_menu.module_id')
			    ->where( 'company_id' , $cid )->where('version' , 'B' )->select();
		return $list;
	}

	/**
	 * 选择模块列表
	 */
	public function selectModule( $cid )
	{
		$selectedIds = $this->getModuleListByCompanyId( $cid );
		$selectedIds = array_column($selectedIds->toArray(), 'name');
		$modules = Db( 'module_store' );
		if( !empty ( $selectedIds ) ){
			$modules = $modules->where( 'name' , 'NOT IN' , $selectedIds );
		}
		$modules = $modules->group('name')->order('title')->select();
		//dump($modules);
		$fn = function( &$version , $name ){
			$children = [];
			foreach ($version as $key => $value) {
				$tmp = [
					'id' => $value[ 'id' ],
					'title' => '<label><input type="radio" class="radio-version" name="'.$name.'" value="'.$value['id'].'">&nbsp;&nbsp;'.$value [ 'version' ]."</label>"
				];
				$children [] = $tmp;
			}
			$tmp = [
				'id' => $value[ 'id' ],
				'title' => '<label><input type="radio" class="radio-version" name="'.$name.'" value="">&nbsp;&nbsp;以上都不选</label>'
			];
			$children [] = $tmp;
			return $children;
		};
		$list = [];
		foreach ($modules as $key => $value) {
			$version = Db( 'module_store' )->where( 'name' , $value[ 'name' ] )->field( 'id,version' )->select();
			$tmp = [
				'id' => $value[ 'id' ],
				'title' => $value [ 'title' ]
			];
			if( !empty( $version ) ){
				$tmp [ 'children' ] = $fn( $version , $value[ 'title' ] );
			}
			$list [] = $tmp;
		}
		return $list;
	}


	/**
	 * 获取模块下载地址
	 */
	public function getDownLoadAddrHost()
	{
		try {
			$addr = CC::getDownloadHostAddress();
		} catch (\Exception $e) {
			return [ 'status'=>false, 'message'=>'获取主机地址异常:'.$e->getMessage(), 'code' => 11001 ];
		}
		if( empty( $addr ) || !isset( $addr[ 'main' ]['address'] ) || !isset( $addr[ 'minor' ]['address'] )  ){
			return [ 'status'=>false, 'message'=>'未找到主机地址配置信息', 'code' => 11002 ];
		}

		if(  $addr[ 'main' ][ 'status' ] = 0  &&  $addr[ 'minor' ][ 'status' ] == 0 ){
			return [ 'status'=>false, 'message'=>'主机地址未被启用', 'code' => 11003 ];
		}

		if( !empty( $addr[ 'main' ]['address'] ) ){
			return $addr[ 'main' ]['address'];
		}

		if( !empty( $addr[ 'minor' ]['address'] ) ){
			return $addr[ 'minor' ]['address'];
		}
		return [ 'status'=>false, 'message'=>'未找到主机地址配置信息', 'code' => 11002 ];
	}

	/**
	 * 	获取模块信息
	 */
	public function getModuleInfo( $storeId )
	{
		$find = Db( 'module_store' )->where( 'id' , $storeId )->find();

		if( empty( $find ) ){
			return [ 'status'=>false, 'message'=>'未检索到模块信息', 'code' => 11004 ];
		}
		return $find;
	}

	/**
	 * 保存授权模块信息
	 * $list [] moduel_store 的id
	 */
	public function saveAuthModule( $cid , $list )
	{
		$insert = [];
		foreach ($list as $key => $store_id ) {
			$store = Db( 'module_store' )->where( 'id' , $store_id )->find();
			$sub = $this->getModuleSubMenu( $store[ 'menu_id' ] , $store[ 'id' ] , $cid , "*".$store[ 'version' ]."*"  );
			$tmp = [
				'menu_id' => $store[ 'menu_id' ],
				'company_id' => $cid,
				'module_id' => $store_id, 
				'custom' => 0,
			];
			$insert [] = $tmp;
			$insert = array_merge( $insert , $sub );
		}
		$res = Db( 'module_menu' )->insertAll( $insert );
		return $res;
	}

	/**
	 * 获取模块子菜单
	 */
	private function getModuleSubMenu ( $menuId , $store_id , $cid , $version )
	{
		$sub = [];
		$list = Db( 'admin_menu' )->where( 'parent_id' , $menuId )->where( 'module_version LIKE "%'.$version.'%"' )->select();
		foreach ($list as $key => $value) {
			$tmp = [
				'menu_id' => $value[ 'id' ],
				'company_id' => $cid,
				'module_id' => $store_id, 
				'custom' => 0,
			]; 
			$sub [] = $tmp;
			$children = $this->getModuleSubMenu( $value[ 'id' ], $store_id , $cid , $version );
			$sub = array_merge( $sub , $children );
		}
		return $sub;
	}

	/**
	 * 删除授权模块信息
	 */
	public function deleteModuleMenu( $cid , $storeId )
	{
		$menus = Db( 'module_menu' )->where( 'company_id' , $cid )->where( 'module_id' , $storeId )->value( 'menu_id' );
		//删除授权信息
		Db('auth_access')->where( 'company' , $cid )->where( 'menu_id' , 'IN' , $menus )->delete();
		$res = Db( 'module_menu' )->where( 'company_id' , $cid )->where( 'module_id' , $storeId )->delete();
		return $res;
	}



	////////////////////////////////////////////////////////////////////////////////////////////////
	//////////模块操作

	/**
	 * 模块安装
	 */
	 
	public function moduleInstall( $storeId , $userId )
	{
		$user = AAZ::getUserInfo( $userId );
		$module = Db( 'module_store' )->where( 'id' , $storeId )->find();
		if( empty($module) ){
			return [ 'status'=>false , 'message'=>'模块不存在' , 'code' => 11006 ];
		}
		$findcode = Db( 'module_menu' )->where( 'company_id' , $user[ 'company_id' ] )->where( 'menu_id' , $module[ 'menu_id' ] )->find();
		$code = $findcode['code'];
		
		if( empty( $findcode['code'] ) ){
			$code = create_module_code( $storeId );
		}else{
			//如果已安装直接返回code
			return $code;
		}
		
		$rmm = new RMM();
		$subList = $rmm->getSubMenuById( $module [ 'menu_id' ]  );
		
		array_push( $subList, $module [ 'menu_id' ] );
		$res = Db( 'module_menu' )->where( 'menu_id' , 'IN' , $subList )->where( 'company_id' , $user[ 'company_id' ] )->update( [ 'code' => $code ] ); 
		if( !$res ){
			return [ 'status'=>false , 'message'=>'模块安装失败' , 'code' => 11007 ];
		}
		return $code;
	}

	/**
	 * 模块卸载
	 */
	public function moduleUninstall( $storeId , $userId )
	{
		$user = AAZ::getUserInfo( $userId );
		$module = Db( 'module_menu' )->where( 'module_id' , $storeId )->where( 'company_id' , $user[ 'company_id' ] )->find();
		if( empty($module) ){
			return [ 'status'=>false , 'message'=>'未检测到模块信息' , 'code' => 11006 ];
		}
		$rmm = new RMM();
		$subList = $rmm->getSubMenuById( $module [ 'menu_id' ]  );
		array_push( $subList, $module [ 'menu_id' ] );
		
		$res = Db( 'module_menu' )->where( 'menu_id' , 'IN' , $subList )->where( 'company_id' , $user[ 'company_id' ] )->update( [ 'code' => NULL ] );   

		if( !$res ){
			return [ 'status'=>false , 'message'=>'模块卸载失败' , 'code' => 11008 ];
		}
		return $res;
	}

	/**
	 * 模块更新菜单操作
	 */
	public function moduleUpdateMenu( $userId , $storeCode , $menu )
	{

		$storeId = get_module_id_by_code( $storeCode );

		if( $storeId == '' ){
			return [ 'status'=>false , 'message'=>'无效的CODE' , 'code' => 11009 ];
		}

		//读取模块信息
		$module = Db( 'module_store' )->where( 'md5( CONCAT(`id`,"20200504") )="'.$storeId.'"' )->find();
		if( !$module ){
			return [ 'status'=>false , 'message'=>'无效的CODE' , 'code' => 11009 ];
		}

		$key = cmf_parse_name( $module[ 'name' ] )."@".$module[ 'version' ];
		
		if( !isset( $menu[ $key ] ) || empty( $menu [ $key ] ) || empty( $module[ 'menu_id' ] )  ){
			return [ 'status'=>false , 'message'=>'未检索到菜单信息' , 'code' => 11010 ];
		}
		//菜单添加版本信息
		$this->updateMenuVersion( $module[ 'menu_id' ] , $module[ 'version' ] );
		
		try {
			$userInfo = $this->getUserInfo( $userId );
			$userInfo [ 'store_id' ] = $module[ 'id' ];
			$userInfo [ 'code' ] = $storeCode;
			//更新菜单库菜单
			$roleAuthMenu = $this->updateAdminMenu( $userInfo , $module[ 'menu_id' ] , "plugin/".cmf_parse_name( $module[ 'name' ] , 1 ) , $module[ 'version' ] ,  $menu [ $key ] );
			//授权菜单
			if( !empty( $roleAuthMenu ) ){
				foreach ($roleAuthMenu as $key => $value) {
					//判断是否已添加
					$have = Db( 'module_menu' )->where( 'company_id' , $value [ 'company_id' ] )->where( 'menu_id' , $value ['menu_id'] )->find();
					if( !$have ){
						Db( 'module_menu' )->insert( $value );
					}
				}
				
			}
		} catch ( \Exception $e ) {
			return [ 'status'=>false , 'message'=>'更新菜单异常:'.$e->getMessage() , 'code' => 11011 ];
		}

		return true;
	}

	/**
	 * 读取用户信息 cid rid uid
	 */
	private function getUserInfo( $userId )
	{
		$info = AAZ::getUserInfo( $userId );
		return [ 'uid'=> $userId , 'cid'=> $info[ 'company_id' ] ];
	}


	/**
	 * 菜单更新
	 */
	/*
	*菜单结构
	 return [
		'module_config@1.0' => [
				[
					'name' => '一级子菜单',
					'controller' => 'Config',
					'action' => 'index', 
					'hasView' => true,
					'display' => false,
					'icon' => '2111',
					'param' => '',
					'describe' => '菜单描述',
					'children' => [

					]
				], 
			]
		];
	 */
	private  function updateAdminMenu( $userInfo , $parent , $app , $menuVersion ,  $menuList )
	{
		$roleAuthMenu = [];//角色授权信息
		foreach ( $menuList as $key => $vo ) {
			//菜单字段信息验证
			if( $this->menuFieldValidate( $vo ) ){
				$controller = cmf_parse_name( $vo[ 'controller' ] , 1 );
				$action = $vo[ 'action' ];
				$controller = str_replace( 'Controller', '', $controller );
				//如果上传主菜单,忽略操作
				if( $controller == 'AdminIndex' && ( $action == 'index' || $action == 'Index' )  ){
					continue;
				}
				$vs 		= "*$menuVersion*" ;

				$info = [
						'name' 			=> 	$vo[ 'name' ] ,
						'app' 			=> 	$app,
						'controller' 	=> 	$controller,
						'action' 		=> 	$action,
						'type' 			=> 	$vo [ 'hasView' ],
						'status' 		=> 	$vo [ 'display' ],
						'list_order' 	=> 	'1000',
						'remark' 		=> 	$vo [ 'remark' ],
						'parent_id' 	=>  $parent,
						'param' 		=>  isset( $vo[ 'param' ] ) ? $vo[ 'param' ] : '',
						'module_version'=>  $vs,
					] ;

				$find 		= Db( 'admin_menu' )->where( [ 'app'=>$app , 'controller'=>$controller , 'action'=>$action ] )->find();
				$custom = 0;
				//自定义菜单
				if( isset( $vo[ 'custom' ] ) && $vo[ 'custom' ] == 1 ){
					$custom = 1;
				}
				
				$addSubMenu = false;
				if( $find ){
					$currentMenuId = $find [ 'id' ] ;
					//更新菜单 禁止开发人员随意修改菜单
					//Db('admin_menu')->where( 'id' , $find [ 'id' ] )->update( $info );
					//菜单存在.更新菜单版本信息 ,如果没有添加版本信息则更新版本信息
					$pos 	= strpos( $find[ 'module_version' ] , $vs );
					if( $pos == false ){
						$this->updateMenuVersion( $find[ 'id' ] , $menuVersion );
					}
				}else{
					//查询的菜单不存在,则添加新菜单
					$currentMenuId = Db('admin_menu')->insertGetId( $info );
				}
				
				if( $currentMenuId && isset( $vo [ 'children' ] ) && !empty( $vo [ 'children' ] ) ){
					//添加子菜单
					$tmp = $this->updateAdminMenu( $userInfo , $currentMenuId , $app , $menuVersion ,  $vo [ 'children' ] );
					$roleAuthMenu = array_merge( $roleAuthMenu , $tmp );
				}

				//权限菜单
				$auth = [ 
					'menu_id' 		=> $currentMenuId,
					'company_id' 	=> $userInfo [ 'cid' ] ,
					'module_id' 	=> $userInfo [ 'store_id' ],
					'custom' 		=> $custom,
					'code' 			=> $userInfo[ 'code' ],
				];
				
				$roleAuthMenu [] = $auth;
			}
		}

		return $roleAuthMenu;
	}

	/**
	 * 更新菜单版本
	 */
	private function updateMenuVersion( $menuId , $version )
	{
		$m = Db( 'admin_menu' )->where( 'id' , $menuId )->where( "module_version LIKE '%*".$version."*%'" )->find();
		if( $m ){
			return true;
		}
		$sql = " UPDATE `cmf_admin_menu` SET `module_version`=CONCAT(`module_version`,',*".$version."*') WHERE `id`=$menuId";
		$res = Db::execute( $sql );
		return $res;
	}

	/**
	 * 菜单字段验证
	 */
	private function menuFieldValidate( $list )
	{
		$rules = [
			'name' 			=> 'require',
			'hasView' 		=> 'require|in:0,1,2',
			'display' 		=> 'require|in:0,1',
			'controller' 	=> 'require',
			'action' 		=> 'require',
			'remark' 		=> 'require',
		];
		$validate = new \think\Validate( $rules ) ;
		$res = $validate->check( $list );
		if( !$res ){
			throw new \Exception( '菜单['.$list['name'].']验证错误信息:'.$validate->getError() );
		}
		return $res ;
	}


}